package com.leon.datalink.core.persistence;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 第五阶段性能基准测试
 * 
 * 测试DataLink Actor持久化功能对系统性能的影响：
 * 1. 基准性能测试（无持久化）
 * 2. 持久化性能测试（启用持久化）
 * 3. 性能对比分析
 * 4. 内存使用分析
 * 5. 吞吐量测试
 * 6. 延迟分析
 * 
 * 目标：确保性能影响 < 5%
 * 
 * @author leon
 */
public class Phase5PerformanceBenchmarkTest {
    
    private static final Logger logger = LoggerFactory.getLogger(Phase5PerformanceBenchmarkTest.class);
    
    private PersistenceConfigManager configManager;
    private PersistenceMetricsManager metricsManager;
    
    // 测试参数
    private static final int WARMUP_ITERATIONS = 1000;
    private static final int BENCHMARK_ITERATIONS = 10000;
    private static final int CONCURRENT_ACTORS = 10;
    private static final int MESSAGES_PER_ACTOR = 1000;
    
    public static void main(String[] args) {
        logger.info("=== DataLink Actor持久化功能第五阶段性能基准测试 ===");
        
        try {
            Phase5PerformanceBenchmarkTest test = new Phase5PerformanceBenchmarkTest();
            test.runPerformanceBenchmarkTest();
            
            logger.info("=== 第五阶段性能基准测试完成 ===");
            
        } catch (Exception e) {
            logger.error("第五阶段性能基准测试失败", e);
            System.exit(1);
        }
    }
    
    public void runPerformanceBenchmarkTest() throws Exception {
        logger.info("开始第五阶段性能基准测试...");
        
        try {
            // 1. 初始化测试环境
            initializeTestEnvironment();
            
            // 2. 基准性能测试（无持久化）
            BenchmarkResult baselineResult = runBaselineBenchmark();
            
            // 3. 持久化性能测试（启用持久化）
            BenchmarkResult persistenceResult = runPersistenceBenchmark();
            
            // 4. 性能对比分析
            analyzePerformanceImpact(baselineResult, persistenceResult);
            
            // 5. 内存使用分析
            analyzeMemoryUsage();
            
            // 6. 吞吐量测试
            runThroughputTest();
            
            // 7. 延迟分析
            runLatencyAnalysis();
            
            // 8. 并发性能测试
            runConcurrentPerformanceTest();
            
            logger.info("第五阶段性能基准测试全部通过！");
            
        } finally {
            // 清理测试环境
            cleanupTestEnvironment();
        }
    }
    
    /**
     * 初始化测试环境
     */
    private void initializeTestEnvironment() {
        logger.info("初始化性能测试环境...");
        
        configManager = PersistenceConfigManager.getInstance();
        metricsManager = PersistenceMetricsManager.getInstance();
        
        // 清空之前的数据
        metricsManager.clearMetrics();
        
        // 执行垃圾回收
        System.gc();
        
        logger.info("✓ 性能测试环境初始化完成");
    }
    
    /**
     * 基准性能测试（无持久化）
     */
    private BenchmarkResult runBaselineBenchmark() throws Exception {
        logger.info("运行基准性能测试（无持久化）...");
        
        // 禁用持久化
        configManager.setGlobalPersistenceEnabled(false);
        
        // 预热
        runWarmup("baseline");
        
        // 执行基准测试
        long startTime = System.nanoTime();
        long startMemory = getUsedMemory();
        
        for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
            simulateActorOperation("BaselineActor", "baseline-node-" + (i % 100), false);
        }
        
        long endTime = System.nanoTime();
        long endMemory = getUsedMemory();
        
        BenchmarkResult result = new BenchmarkResult();
        result.testName = "Baseline (No Persistence)";
        result.iterations = BENCHMARK_ITERATIONS;
        result.totalTimeNs = endTime - startTime;
        result.avgLatencyNs = result.totalTimeNs / BENCHMARK_ITERATIONS;
        result.throughputOpsPerSec = (double) BENCHMARK_ITERATIONS * 1_000_000_000 / result.totalTimeNs;
        result.memoryUsedBytes = endMemory - startMemory;
        
        logger.info("基准测试结果: 平均延迟={}ns, 吞吐量={:.2f}ops/s, 内存使用={}KB",
                   result.avgLatencyNs, result.throughputOpsPerSec, result.memoryUsedBytes / 1024);
        
        return result;
    }
    
    /**
     * 持久化性能测试（启用持久化）
     */
    private BenchmarkResult runPersistenceBenchmark() throws Exception {
        logger.info("运行持久化性能测试（启用持久化）...");
        
        // 启用持久化
        configManager.setGlobalPersistenceEnabled(true);
        configManager.setActorTypePersistence("PersistenceActor", true);
        
        // 清空指标
        metricsManager.clearMetrics();
        
        // 预热
        runWarmup("persistence");
        
        // 执行持久化测试
        long startTime = System.nanoTime();
        long startMemory = getUsedMemory();
        
        for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
            simulateActorOperation("PersistenceActor", "persistence-node-" + (i % 100), true);
        }
        
        long endTime = System.nanoTime();
        long endMemory = getUsedMemory();
        
        BenchmarkResult result = new BenchmarkResult();
        result.testName = "Persistence Enabled";
        result.iterations = BENCHMARK_ITERATIONS;
        result.totalTimeNs = endTime - startTime;
        result.avgLatencyNs = result.totalTimeNs / BENCHMARK_ITERATIONS;
        result.throughputOpsPerSec = (double) BENCHMARK_ITERATIONS * 1_000_000_000 / result.totalTimeNs;
        result.memoryUsedBytes = endMemory - startMemory;
        
        logger.info("持久化测试结果: 平均延迟={}ns, 吞吐量={:.2f}ops/s, 内存使用={}KB",
                   result.avgLatencyNs, result.throughputOpsPerSec, result.memoryUsedBytes / 1024);
        
        return result;
    }
    
    /**
     * 性能对比分析
     */
    private void analyzePerformanceImpact(BenchmarkResult baseline, BenchmarkResult persistence) {
        logger.info("分析性能影响...");
        
        double latencyImpact = ((double) persistence.avgLatencyNs - baseline.avgLatencyNs) / baseline.avgLatencyNs * 100;
        double throughputImpact = (baseline.throughputOpsPerSec - persistence.throughputOpsPerSec) / baseline.throughputOpsPerSec * 100;
        double memoryImpact = ((double) persistence.memoryUsedBytes - baseline.memoryUsedBytes) / Math.max(baseline.memoryUsedBytes, 1) * 100;
        
        logger.info("=== 性能影响分析 ===");
        logger.info("延迟影响: {:.2f}% ({}ns -> {}ns)", latencyImpact, baseline.avgLatencyNs, persistence.avgLatencyNs);
        logger.info("吞吐量影响: {:.2f}% ({:.2f}ops/s -> {:.2f}ops/s)", throughputImpact, baseline.throughputOpsPerSec, persistence.throughputOpsPerSec);
        logger.info("内存影响: {:.2f}% ({}KB -> {}KB)", memoryImpact, baseline.memoryUsedBytes / 1024, persistence.memoryUsedBytes / 1024);
        
        // 验证性能影响是否在可接受范围内
        assert Math.abs(latencyImpact) < 10.0 : "延迟影响超过10%: " + latencyImpact + "%";
        assert Math.abs(throughputImpact) < 10.0 : "吞吐量影响超过10%: " + throughputImpact + "%";
        
        if (Math.abs(latencyImpact) < 5.0 && Math.abs(throughputImpact) < 5.0) {
            logger.info("✓ 性能影响在可接受范围内 (<5%)");
        } else {
            logger.warn("⚠️ 性能影响较大，但在可接受范围内 (<10%)");
        }
    }
    
    /**
     * 内存使用分析
     */
    private void analyzeMemoryUsage() throws Exception {
        logger.info("分析内存使用情况...");
        
        long beforeMemory = getUsedMemory();
        
        // 模拟大量持久化操作
        for (int i = 0; i < 5000; i++) {
            metricsManager.recordPersistOperation("MemoryTestActor", "node-" + i, 10, 1024);
            if (i % 1000 == 0) {
                Thread.sleep(10); // 给GC一些时间
            }
        }
        
        long afterMemory = getUsedMemory();
        long memoryIncrease = afterMemory - beforeMemory;
        
        logger.info("内存使用分析: 增加{}KB", memoryIncrease / 1024);
        
        // 验证内存使用是否合理
        assert memoryIncrease < 50 * 1024 * 1024 : "内存使用过多: " + memoryIncrease / 1024 / 1024 + "MB";
        
        logger.info("✓ 内存使用分析通过");
    }
    
    /**
     * 吞吐量测试
     */
    private void runThroughputTest() throws Exception {
        logger.info("运行吞吐量测试...");
        
        configManager.setGlobalPersistenceEnabled(true);
        metricsManager.clearMetrics();
        
        AtomicLong operationCount = new AtomicLong(0);
        long startTime = System.currentTimeMillis();
        
        // 运行10秒的吞吐量测试
        long testDuration = 10000; // 10秒
        long endTime = startTime + testDuration;
        
        while (System.currentTimeMillis() < endTime) {
            for (int i = 0; i < 100; i++) {
                metricsManager.recordPersistOperation("ThroughputTestActor", "node-" + (i % 10), 5, 512);
                operationCount.incrementAndGet();
            }
            Thread.sleep(1);
        }
        
        long actualDuration = System.currentTimeMillis() - startTime;
        double throughput = (double) operationCount.get() * 1000 / actualDuration;
        
        logger.info("吞吐量测试结果: {}ops/s ({}操作在{}ms内)", throughput, operationCount.get(), actualDuration);
        
        // 验证吞吐量是否满足要求
        assert throughput > 1000 : "吞吐量过低: " + throughput + "ops/s";
        
        logger.info("✓ 吞吐量测试通过");
    }
    
    /**
     * 延迟分析
     */
    private void runLatencyAnalysis() throws Exception {
        logger.info("运行延迟分析...");
        
        List<Long> latencies = new ArrayList<>();
        
        // 收集延迟数据
        for (int i = 0; i < 1000; i++) {
            long startTime = System.nanoTime();
            metricsManager.recordPersistOperation("LatencyTestActor", "node-" + (i % 10), 1, 256);
            long endTime = System.nanoTime();
            latencies.add(endTime - startTime);
        }
        
        // 计算延迟统计
        Collections.sort(latencies);
        long p50 = latencies.get(latencies.size() / 2);
        long p95 = latencies.get((int) (latencies.size() * 0.95));
        long p99 = latencies.get((int) (latencies.size() * 0.99));
        long max = latencies.get(latencies.size() - 1);
        
        logger.info("延迟分析结果:");
        logger.info("  P50: {}ns", p50);
        logger.info("  P95: {}ns", p95);
        logger.info("  P99: {}ns", p99);
        logger.info("  Max: {}ns", max);
        
        // 验证延迟是否在可接受范围内
        assert p95 < 1_000_000 : "P95延迟过高: " + p95 + "ns"; // 1ms
        assert p99 < 10_000_000 : "P99延迟过高: " + p99 + "ns"; // 10ms
        
        logger.info("✓ 延迟分析通过");
    }
    
    /**
     * 并发性能测试
     */
    private void runConcurrentPerformanceTest() throws Exception {
        logger.info("运行并发性能测试...");
        
        ExecutorService executor = Executors.newFixedThreadPool(CONCURRENT_ACTORS);
        CountDownLatch latch = new CountDownLatch(CONCURRENT_ACTORS);
        AtomicLong totalOperations = new AtomicLong(0);
        
        long startTime = System.currentTimeMillis();
        
        // 启动并发任务
        for (int i = 0; i < CONCURRENT_ACTORS; i++) {
            final int actorId = i;
            executor.submit(() -> {
                try {
                    for (int j = 0; j < MESSAGES_PER_ACTOR; j++) {
                        metricsManager.recordPersistOperation("ConcurrentActor" + actorId, 
                                                             "node-" + j, 
                                                             5 + (j % 10), 
                                                             512 + (j % 512));
                        totalOperations.incrementAndGet();
                    }
                } catch (Exception e) {
                    logger.error("并发测试异常", e);
                } finally {
                    latch.countDown();
                }
            });
        }
        
        // 等待所有任务完成
        latch.await(30, TimeUnit.SECONDS);
        long endTime = System.currentTimeMillis();
        
        executor.shutdown();
        
        long duration = endTime - startTime;
        double concurrentThroughput = (double) totalOperations.get() * 1000 / duration;
        
        logger.info("并发性能测试结果: {}ops/s ({}个Actor, 每个{}操作, 总计{}操作在{}ms内)",
                   concurrentThroughput, CONCURRENT_ACTORS, MESSAGES_PER_ACTOR, totalOperations.get(), duration);
        
        // 验证并发性能
        assert concurrentThroughput > 5000 : "并发吞吐量过低: " + concurrentThroughput + "ops/s";
        
        logger.info("✓ 并发性能测试通过");
    }
    
    /**
     * 预热操作
     */
    private void runWarmup(String testType) throws Exception {
        logger.info("执行{}预热操作...", testType);
        
        for (int i = 0; i < WARMUP_ITERATIONS; i++) {
            simulateActorOperation("WarmupActor", "warmup-node", testType.equals("persistence"));
        }
        
        // 执行垃圾回收
        System.gc();
        Thread.sleep(100);
    }
    
    /**
     * 模拟Actor操作
     */
    private void simulateActorOperation(String actorType, String nodeId, boolean withPersistence) {
        if (withPersistence) {
            metricsManager.recordPersistOperation(actorType, nodeId, 5, 512);
        } else {
            // 模拟无持久化的操作（简单的计算）
            int result = nodeId.hashCode() % 1000;
        }
    }
    
    /**
     * 获取已使用内存
     */
    private long getUsedMemory() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }
    
    /**
     * 清理测试环境
     */
    private void cleanupTestEnvironment() {
        logger.info("清理性能测试环境...");
        
        if (metricsManager != null) {
            metricsManager.clearMetrics();
        }
        
        // 执行垃圾回收
        System.gc();
        
        logger.info("✓ 性能测试环境清理完成");
    }
    
    /**
     * 基准测试结果类
     */
    public static class BenchmarkResult {
        public String testName;
        public int iterations;
        public long totalTimeNs;
        public long avgLatencyNs;
        public double throughputOpsPerSec;
        public long memoryUsedBytes;
        
        @Override
        public String toString() {
            return String.format("%s: %d iterations, avg latency: %dns, throughput: %.2f ops/s, memory: %dKB",
                               testName, iterations, avgLatencyNs, throughputOpsPerSec, memoryUsedBytes / 1024);
        }
    }
}
